package com.wiscamp.ninechapters.tags.infrastructure.repositories;

import com.wiscamp.ninechapters.tags.domain.models.Subject;
import com.wiscamp.ninechapters.tags.domain.repositories.SubjectRepository;
import com.wiscamp.ninechapters.tags.infrastructure.converters.SubjectConverter;
import com.wiscamp.ninechapters.tags.infrastructure.mappers.SubjectMapper;
import com.wiscamp.ninechapters.tags.infrastructure.mappers.SubjectViewMapper;
import com.wiscamp.ninechapters.tags.infrastructure.po.SubjectPO;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.domain.BaseRepository;
import cube.ddd.utils.PersistenceUtils;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class SubjectRepositoryImpl extends BaseRepository implements SubjectRepository {

    private final SubjectMapper subjectMapper;

    private final SubjectViewMapper subjectViewMapper;

    public SubjectRepositoryImpl(SubjectMapper subjectMapper, SubjectViewMapper subjectViewMapper) {
        this.subjectMapper = subjectMapper;
        this.subjectViewMapper = subjectViewMapper;
    }

    @HandleDataException
    private SubjectPO getSubjectPO(@Min(0) long id) {
        return PersistenceUtils.findById(id, subjectMapper::findById);
    }

    @HandleDataException
    public Subject getSubject(@Min(0) long subjectId) {
        return PersistenceUtils.findEntityById(subjectId, subjectViewMapper::findById, SubjectConverter.Instance::toSubjectByView);
    }

    @HandleDataException
    public Subject getSubjectByCode(@NotBlank String subjectCode) {
        return PersistenceUtils.getEntityByText(subjectCode, subjectViewMapper::findBySubjectCode, SubjectConverter.Instance::toSubjectByView);
    }

    @HandleDataException
    public Collection<Subject> getSubjectsByName(@NotBlank String subjectName) {
        return PersistenceUtils.getEntitiesByText(subjectName, subjectViewMapper::findListBySubjectName, SubjectConverter.Instance::toSubjectByView);
    }

    @HandleDataException
    public Collection<Subject> getAvailableSubjects() {
        return PersistenceUtils.getEntities(subjectViewMapper::findListByAvailable, SubjectConverter.Instance::toSubjectByView);
    }

    @HandleDataException
    public Subject saveSubject(@NotNull Subject subject) {
        return PersistenceUtils.saveEntity(subject, subjectMapper::saveAndFlush,
                SubjectConverter.Instance::toSubjectPO, SubjectConverter.Instance::toSubject);

        /*var newId = subject.getSubjectId();
        if (subject.getSubjectId() <= 0) {
            var newSubject = PersistenceUtils.createEntity(subject, subjectMapper::saveAndFlush,
                    SubjectConverter.Instance::toSubjectPO, SubjectConverter.Instance::toSubject);
            newId = newSubject.getSubjectId();
        } else {
            var existedPO = getSubjectPO(subject.getSubjectId());
            if (existedPO == null) existedPO = new SubjectPO();
            PersistenceUtils.updateEntity(subject, existedPO, subjectMapper::saveAndFlush,
                    SubjectConverter.Instance::toSubjectPO, SubjectConverter.Instance::toSubject);
        }*/

        // return getSubject(newSubject.getSubjectId());
        //return newSubject;
    }
}
